home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / Telnet 2.5.src.ThinkC / source / bkgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-04  |  38.7 KB  |  1,564 lines  |  [TEXT/MPS ]

  1. /*
  2. *  Background procedures for rcp and ftp
  3. *             11/86          Tim Krauskopf
  4. *  National Center for Supercomputing Applications
  5. *
  6. ****************************************************************************
  7. *                                                                          *
  8. *      part of:                                                            *
  9. *      Network utilities for NCSA Telnet                                   *
  10. *      by Tim Krauskopf                                                    *
  11. *                                                                          *
  12. *      National Center for Supercomputing Applications                     *
  13. *      152 Computing Applications Building                                 *
  14. *      605 E. Springfield Ave.                                             *
  15. *      Champaign, IL  61820                                                *
  16. *                                                                          *
  17. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  18. *                                                                          *
  19. ****************************************************************************
  20. *
  21. */
  22. #include <stdio.h>
  23. #include <fcntl.h>
  24. #include <string.h>
  25.  
  26. #include <Memory.h>
  27. #include <CType.h>
  28. #include <Dialogs.h>
  29. #include <ToolUtils.h>    /* BYU - for GetIndString() */
  30.  
  31. #include "whatami.h"
  32. #include "hostform.h"
  33. #include "menu.h"
  34. #include "user.h"
  35. #include "tools.h"
  36. #include "util.h"
  37. #include "macutil.h"
  38. #include "macbinary.h"
  39. #include "binsubs.h"
  40. #include "configrec.h"
  41. #include "maclook.h"
  42.  
  43. #define HTELNET 23
  44. #define HRSHD 514
  45. #define HFTP 21
  46. #define BUFFERS 8000
  47. #define PATHLEN 256
  48. #define MSG_RESOURCE_ID 23227    /* BYU */
  49.  
  50. #ifdef PC
  51.  
  52. #define RCPSEGSIZE 1024
  53. #define EOLCHAR 10
  54.  
  55. #ifdef MSC
  56. #define O_RAW O_BINARY
  57. #endif
  58.  
  59. #else
  60.  
  61. #define MACBINARY
  62.  
  63. #ifdef MACBINARY
  64. int
  65.     MacBinary=0;
  66. MBFile
  67.     *MBopen(),
  68.     *mbfp=NULL;
  69. extern int
  70.     defaultv;                        /* Default Volume from Maclook/Menu */
  71. #endif
  72.  
  73. #define RCPSEGSIZE 512
  74. #define O_RAW O_RDONLY
  75. #define EOLCHAR 13
  76. #endif
  77.  
  78.  
  79. int32 atol(),lseek();
  80.  
  81. extern void ftpmess();
  82. char *firstname(),*nextname(),*nextfile;
  83.  
  84. static  int
  85.     ftpenable=0,                /* is file transfer enabled? */
  86.     rcpenable=0,                /* is rcp enabled? */
  87. /*    ftpdata=-1,                    /* port for ftp data connection */    /* BYU 2.4.16 */
  88. /*    fnum=-1,                    /* port number for incoming ftp */    /* BYU 2.4.16 */
  89.     rsnum=-1,                    /* port number for incoming rshell */
  90.     rserr=-1;                    /* port number for rshd() stderr */
  91.  
  92. #ifdef PC
  93. static unsigned char xs[BUFFERS+10],    /* buffer space for file transfer */
  94.         pathname[PATHLEN],            /* space to keep path names */
  95.         newfile[PATHLEN],            /* current file being received */
  96.         myuser[17],                    /* user name on my machine */
  97.         hisuser[17],                /* user name on his machine */
  98.         waitchar;                    /* character waiting for from net */
  99. #else
  100. static  unsigned char *xs=0L,    /* buffer space for file transfer */
  101.         *pathname=0L,            /* space to keep path names */
  102.         *newfile=0L,            /* current file being received */
  103.         myuser[17],                    /* user name on my machine */
  104.         hisuser[17],                /* user name on his machine */
  105.         waitchar;                    /* character waiting for from net */
  106. #endif PC
  107.  
  108. static int 
  109.     curstate = -1,            /* state machine for background processes */
  110.     retstate = 200,            /* to emulate a subroutine call */
  111.     ftpstate = 0,            /* state of the ftp data transfer */
  112.     isdir=0,                /* flag for rcp target pathname */
  113.     waitpos=0,                /* marker for gathering strings from net */
  114.     cnt=0,                    /* number of characters from last netread() */
  115.     fh=0,                    /* file handle when transfer file is open */
  116.     ftpfh=0,                /* file handle for ftp data */
  117.     rc=0,                    /* telnet flag */
  118.     xp=0,                    /* general pointer */
  119.     towrite=0,                /* file transfer pointer */
  120.     len=0;                    /* file transfer length */
  121.  
  122. static long int
  123.     filelen=0L;                /* length of current file for transfer */
  124.  
  125. short mainport[NPORTS];        /* BYU 2.4.16 - map FTP data port to main port */
  126. short dataport[NPORTS];        /* BYU 2.4.16 - map FTP main port to data port */
  127. short mainstate[NPORTS];    /* BYU 2.4.16 */
  128. short datastate[NPORTS];    /* BYU 2.4.16 */
  129. short retnstate[NPORTS];
  130. short fileport[NPORTS];
  131.  
  132. extern char * mungbuf;
  133. static char crfound=0;
  134.  
  135.  
  136. extern char Sptypes[];        /* BYU 2.4.16 - flags for port #'s */
  137.  
  138. #define PFTP 1
  139. #define PRCP 2
  140. #define PDATA 3
  141.  
  142. #ifdef PC
  143.  
  144. #define ga()  while (!netwrite(rsnum,"",1)) netsleep(0)
  145.  
  146. /************************************************************************/
  147. /*  unsetrshd
  148. *   remove the acceptance of rshd calls (rcp)
  149. */
  150. unsetrshd()
  151.     {
  152.     netclose(rsnum);
  153.     rsnum = -1;
  154.     rcpenable = 0;
  155. }
  156.  
  157. /************************************************************************/
  158.  
  159. setrshd()
  160. {
  161.     int i;
  162. /*
  163. *  set up to receive a rsh call connection 
  164. */
  165.     if (rsnum >= 0)
  166.         return(0);
  167.     curstate = 199;                    /* waiting for connection */
  168.     i = netsegsize(RCPSEGSIZE);
  169.     rsnum = netlisten(HRSHD,0);        /* BYU 2.4.15 */
  170.     netsegsize(i);
  171.     if (rsnum >= 0)
  172.         Sptypes[rsnum] = PRCP;
  173.  
  174.     rcpenable = 1;
  175. }
  176.  
  177.  
  178. /************************************************************************/
  179. /*  rshell
  180. *   take an incoming rshell request and service it.  Designed to handle
  181. *   rcp primarily.
  182. */
  183. rshd(code)
  184.     int code;
  185.     {
  186.     int i,j;
  187.  
  188.     if (!rcpenable)
  189.         return(0);
  190.  
  191.     switch (curstate) {
  192.         case 199:                    /* wait to get started */
  193.             if (code != CONOPEN)
  194.                 break;
  195.  
  196.             curstate = 0;
  197.             netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  198.  
  199.             break;
  200.             
  201. /*
  202. * in effect, this is a subroutine that captures network traffic while
  203. * waiting for a specific character to be received
  204. */
  205.         case 50:
  206.             while (0 < (cnt = netread(rsnum,&xs[waitpos],1))) {
  207.                 if (xs[waitpos] == waitchar) {
  208.                     curstate = retstate;
  209.                     netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  210.                     break;
  211.                 }
  212.                 else 
  213.                     waitpos += cnt;
  214.             }
  215.             netpush(rsnum);
  216.             break;
  217.  
  218.         case 51:                /* for recursion, passes straight through */
  219.             break;
  220.  
  221.         case 0:                    /* waiting for first string */
  222.             retstate = 1;
  223.             curstate = 50;
  224.             waitchar = 0;
  225.             waitpos = 0;
  226.             netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  227.             break;
  228.  
  229.         case 1:                    /* we have received stderr port number */
  230.             i = atoi(xs);        /* port number */
  231.             curstate = 51;
  232. #ifdef notneeded
  233. /*
  234. *  caution, netrespond calls netsleep()
  235. *  which will call this routine
  236. *  careful with the synchronicity!
  237. */
  238.             if (i)        /* zero means, don't bother */
  239.                 rserr = netrespond(i,rsnum,1);    /* respond to rsh */
  240.             else
  241. #else
  242.             if (i) {
  243.                 cnt = -1;        /* abort it all, we don't take rsh */
  244.                 break;
  245.             }
  246.             else
  247. #endif
  248.                 rserr = -1;
  249.  
  250.             retstate = 2; curstate = 50;
  251.             waitpos = 0; waitchar = 0;
  252.             break;
  253.  
  254.         case 2:                /* get user name, my machine */
  255.             strncpy(myuser,xs,16);
  256.  
  257.             retstate = 3; curstate = 50;
  258.             waitpos = 0; waitchar = 0;
  259.             break;
  260.  
  261.         case 3:             /* get user name, his machine */
  262.             strncpy(hisuser,xs,16);
  263. /*            ftransinfo(hisuser); */
  264.  
  265.             retstate = 4; curstate = 50;
  266.             waitchar = 0; waitpos = 0;
  267.  
  268.             break;
  269.  
  270.         case 4:
  271. /*            ftransinfo(xs);*/
  272. /*
  273. * ACK receipt of command line
  274. */
  275.             if (rserr >= 0)
  276.                 netwrite(rserr,&xp,1);        /* send null byte */
  277.             else {
  278.                 ga();            /* send NULL on main connection */
  279.             }
  280.  
  281.             if (!strncmp(xs,"rcp ",4)) {
  282. /*
  283. *  rcp will be using wildcards, target must be a directory
  284. */
  285.                 if (!strncmp(&xs[4],"-d -t",5)) {
  286.                     strncpy(pathname,&xs[10],PATHLEN);
  287.                     if (direxist(pathname)) {
  288. /*                        ftransinfo("no directory by that name ");*/
  289.                         netwrite(rsnum,"\001 No dir found ",16);
  290.                         netpush(rsnum);
  291.                         cnt = -1;
  292.                         break;
  293.                     }
  294.  
  295.                     isdir = 1;
  296.                     retstate = 20; curstate = 50;
  297.                     waitchar = '\012'; waitpos = 0;
  298.  
  299.                     ga();        /* ready for them to start */
  300.                     break;
  301.                 }
  302. /*
  303. * target could be a directory or a complete file spec
  304. */
  305.                 if (!strncmp(&xs[4],"-t",2)) {
  306.                     strncpy(pathname,&xs[7],PATHLEN);
  307.                     if (!direxist(pathname)) 
  308.                         isdir = 1;
  309.                     else
  310.                         isdir = 0;
  311.  
  312.                     retstate = 20 ; curstate = 50;
  313.                     waitchar = '\012'; waitpos = 0;
  314.  
  315.                     ga();            /* ready for rcp to start */
  316.                     break;
  317.                 }
  318. /*
  319. *  rcp is requesting me to transfer file(s) (or giving directory name)
  320. */
  321.                 if (!strncmp(&xs[4],"-f",2)) {
  322.                     strncpy(pathname,&xs[7],PATHLEN);
  323.  
  324. /*
  325. *  direxist returns whether the path spec refers to a directory, and if
  326. *  it does, prepares it as a prefix.  Therefore, if it is a dir, we append
  327. *  a '*' to it to wildcard all members of the directory.
  328. *  Firstname() takes a file spec (with wildcards) and returns a pointer
  329. *  to a prepared ACTUAL file name.  nextname() returns successive ACTUAL
  330. *  filenames based on firstname().
  331. */
  332.                     if (!direxist(pathname)) {
  333.                         i = strlen(pathname);
  334.                         pathname[i] = '*';        /* all members of directory*/
  335.                         pathname[++i] = '\0';
  336.                     }
  337.                     nextfile = firstname(pathname);
  338.  
  339.                     if (nextfile == NULL) {
  340. /*                        ftransinfo(" file or directory not found ");*/
  341.                         netwrite(rsnum,"\001 File not found ",18);
  342.                         netpush(rsnum);
  343.                         cnt = -1;
  344.                     }
  345.                     else {
  346.                         /* wait for other side to be ready */
  347.                         retstate = 30;    curstate = 50;
  348.                         waitchar = 0; waitpos = 0;
  349.                     }
  350.                     break;
  351.                 }
  352.             }
  353.  
  354.             break;
  355.  
  356.         case 20:
  357.             xs[waitpos] = '\0';        /* add terminator */
  358.  
  359. /*
  360. *  get working values from command line just received
  361. *  open file for receive
  362. */
  363.             if (xs[0] != 'C' || xs[5] != ' ') {
  364. /*                ftransinfo(" Cannot parse filename line "); */
  365.                 netwrite(rsnum,"\001 Problem with file name ",26);
  366.                 cnt = -1;
  367.                 break;
  368.             }
  369.  
  370.             filelen = atol(&xs[6]);
  371.  
  372.             for (i = 6; xs[i] != ' '; i++) 
  373.                 if (!xs[i]) {
  374. /*                    ftransinfo(" premature EOL ");*/
  375.                     netwrite(rsnum,"\001 Problem with file name ",26);
  376.                     cnt = -1;
  377.                     break;
  378.                 }
  379.  
  380.             strcpy(newfile,pathname);        /* path spec for file */
  381.  
  382.             if (isdir)                        /* add file name for wildcards */
  383.                 strcat(newfile,&xs[++i]);
  384.  
  385.             if (0 > (fh = creat(newfile,O_RAW))) {
  386.                 netwrite(rsnum,"\001 Cannot open file for write ",29);
  387.                 cnt = -1;
  388.                 break;
  389.             }
  390.             netputevent(USERCLASS,RCPBEGIN,-1);
  391.             ga();                            /* start sending the file to me */
  392.             xp = len = 0;
  393.             curstate = 21;                    /* receive file, fall through */
  394.             break;
  395.  
  396.         case 21:
  397.             do {
  398.             /* wait until xs is full before writing to disk */
  399.                 if (len <= 0) {
  400.                     if (xp) {
  401.                         write(fh,xs,xp);
  402.                         xp = 0;
  403.                     }
  404.                     if (filelen > (long)BUFFERS)
  405.                         len = BUFFERS;
  406.                     else
  407.                         len = (int)filelen;
  408.                 }
  409.  
  410.                 cnt = netread(rsnum,&xs[xp],len);
  411.  
  412.                 filelen -= (long)cnt;
  413.                 len -= cnt;
  414.                 xp += cnt;
  415.  
  416. /*                printf(" %ld %d %d %d ",filelen,len,xp,cnt);
  417.                 n_row(); n_puts(""); */
  418.  
  419.                 if (filelen <= 0L || cnt < 0) {
  420.                     write(fh,xs,xp);        /* write last block */
  421.                     close(fh);
  422.                     fh = 0;
  423.                     
  424.                     /* wait for NULL byte at end after closing file */
  425.                     curstate = 50;  retstate = 22;
  426.                     waitchar = 0;   waitpos = 0;
  427.                     break;
  428.                 }
  429.  
  430.             } while (cnt > 0);
  431.             break;
  432.  
  433.         case 22:
  434.             /* cause next sequence of bytes to be saved as next filename
  435.                 to transfer     */
  436.             ga();            /* tell other side, I am ready */
  437.             waitchar = '\012'; waitpos = 0;
  438.             curstate = 50; retstate = 20;
  439.             break;
  440.  
  441. /*
  442. *  transfer file(s) to the sun via rcp
  443. */
  444.         case 30:
  445.             if (0 > (fh = open(nextfile,O_RAW))) {
  446.                 netwrite(rsnum,"\001 File not found ",19);
  447. /*                ftransinfo("Cannot open file to transfer: ");
  448.                 ftransinfo(nextfile); */
  449.                 cnt = -1;
  450.                 break;
  451.             }
  452.             netputevent(USERCLASS,RCPBEGIN,-1);
  453.             filelen = lseek(fh,0L,(short)2);    /* how long is file? */
  454.             lseek(fh,0L,0);                /* back to beginning */
  455.  
  456.             for (i=0,j=-1; nextfile[i] ; i++)
  457.                 if (nextfile[i] == '\\')
  458.                     j = i;
  459.  
  460.             sprintf(xs,"C0755 %lu %s\012",filelen,&nextfile[j+1]);
  461.             netwrite(rsnum,xs,strlen(xs));    /* send info to other side */
  462.  
  463. /*            ftransinfo(xs);                     check it */
  464.  
  465.             retstate = 31; curstate = 50;
  466.             waitchar = 0;  waitpos = 0;
  467.  
  468.             towrite = xp = 0;
  469.             break;
  470.  
  471.         case 31:
  472. /*
  473. *   we are in the process of sending the file 
  474. */
  475.             netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  476.  
  477.             if (towrite <= xp) {
  478.                 towrite = read(fh,xs,BUFFERS);
  479.                 xp = 0;
  480.                 filelen -= (long)towrite;
  481.             }
  482.             i = netwrite(rsnum,&xs[xp],towrite-xp);
  483.             if (i > 0)
  484.                 xp += i;
  485.  
  486. /*            printf(" %d %d %d %ld\012",i,xp,towrite,filelen);
  487.             n_row();
  488. */
  489. /*
  490. *  done if:  the file is all read from disk and all sent
  491. *  or other side has ruined connection
  492. */
  493.             if ((filelen <= 0L && xp >= towrite) || netest(rsnum)) {
  494.                 close(fh);
  495.                 fh = 0;
  496.                 nextfile = nextname();        /* case of wildcards */
  497.                 ga(); 
  498.                 netputuev(SCLASS,RCPACT,rsnum);
  499.                 if (nextfile == NULL)
  500.                     retstate = 32;
  501.                 else
  502.                     retstate = 30;
  503.                 curstate = 50;
  504.                 waitchar = 0;    waitpos = 0;
  505.             }
  506.             break;
  507.         case 32:
  508.             cnt = -1;
  509.             break;
  510.         case 5:
  511.             break;
  512.         default:
  513.             break;
  514.  
  515.     }
  516.  
  517. /*
  518. *  after reading from connection, if the connection is closed,
  519. *  reset up shop.
  520. */
  521.     if (cnt < 0) {
  522.         if (fh > 0) {
  523.             close(fh);
  524.             fh = 0;
  525.         }
  526.         curstate = 5;
  527.         cnt = 0;
  528.         netclose(rsnum);
  529.         rsnum = -1;
  530.         netputevent(USERCLASS,RCPEND,-1);
  531.  
  532.         setrshd();                    /* reset for next transfer */
  533.     }
  534.  
  535.  
  536. }
  537.  
  538. #endif
  539.  
  540. /***********************************************************************/
  541. /***********************************************************************/
  542. /***********************************************************************/
  543. /************************************************************************/
  544. /*  ftp section
  545. *   This should be extracted from rcp so that it compiles cleanly
  546. */
  547.  
  548. #if 0    /* BYU - replaced by CRESP code below */
  549. #define CRESP(A)  netpush(fnum);netwrite(fnum, messs[(A)], strlen(messs[(A)]))
  550. #endif    /* BYU */
  551.  
  552. #define FASCII 0
  553. #define FIMAGE O_RAW
  554. #define FAMODE 0
  555. #define FIMODE 1
  556. #define FMMODE 2            /* Mac Binary, when ready */
  557.  
  558. static int rfstate,
  559.     portnum[NPORTS][8],            /* BYU 2.4.16 */
  560.     ftpfilemode=FASCII,            /* how to open ze file */
  561.     ftptmode=FAMODE;            /* how to transfer ze file on net */
  562.  
  563. /*static uint16 fdport;        /* BYU 2.4.16 - made local to rftpd() */
  564.  
  565. extern int                     /* BYU 2.4.16 */
  566.     EtherNet;                /* BYU 2.4.16 - Signify Drivers */
  567.  
  568. unsigned char messs[100];        /* BYU */
  569.  
  570. void CRESP(fnum,msg_number) int fnum,msg_number; {    /* BYU 2.4.16 */
  571.   GetIndString(messs,MSG_RESOURCE_ID,msg_number+1);    /* BYU */
  572.   netpush(fnum);                                    /* BYU */
  573.   netwrite(fnum, &messs[1], (int) messs[0]);        /* BYU - 2.4.9 */
  574. }                                                    /* BYU */
  575.  
  576. void setftp
  577.   (
  578.     void
  579.   )
  580.     {
  581.     short fnum,i1;                            /* BYU 2.4.16 */
  582.  
  583. /*
  584. *  set up to receive a telnet connection for ftp commands
  585. */
  586.     rfstate = 0;
  587.     ftpstate = 0;
  588.  
  589. /* Listen for FTP if we're not listening already */        /* BYU 2.4.16 */
  590.  
  591.     for (i1 = 0; i1 < NPORTS; i1++)                                         /* BYU 2.4.16 */
  592.         if ((Sptypes[i1] == PFTP) && (netporttype(i1) == NOT_FROM_SLIP))    /* BYU 2.4.16 */
  593.             break;                                                            /* BYU 2.4.16 */
  594.  
  595.     if (i1 >= NPORTS) {                                /* BYU 2.4.16 - non-SLIP listen */
  596.         fnum = netlisten(HFTP,NOT_FROM_SLIP);        /* BYU 2.4.16 - MacTCP listen */
  597.         ftpenable = 1;                                /* BYU 2.4.16 */
  598.  
  599.         if (fnum >= 0) {                            /* BYU 2.4.16 - signal that events should be caught */
  600.             Sptypes[fnum] = PFTP;                    /* BYU 2.4.16 */
  601.             dataport[fnum] = -1;                    /* BYU 2.4.16 - no data needed yet */
  602.             mainstate[fnum] = 0;                    /* BYU 2.4.16 */
  603.             datastate[fnum] = 0;                    /* BYU 2.4.16*/
  604.             retnstate[fnum] = 200;                    /* BYU 2.4.16 */
  605.         }                                            /* BYU 2.4.16 */
  606.     }                                                /* BYU 2.4.16 */
  607.  
  608. /* Listen for SLIP FTP using NCSA driver if the above is a MacTCP listen */    /* BYU 2.4.16 */
  609.  
  610.     if (EtherNet == -99) {                                        /* BYU 2.4.16 - MacTCP? */
  611.  
  612.         for (i1 = 0; i1 < NPORTS; i1++)                                     /* BYU 2.4.16 */
  613.             if ((Sptypes[i1] == PFTP) && (netporttype(i1) == FROM_SLIP))    /* BYU 2.4.16 */
  614.                 break;                                                        /* BYU 2.4.16 */
  615.  
  616.         if (i1 >= NPORTS) {                            /* BYU 2.4.16 - non-SLIP listen */
  617.             fnum = netlisten(HFTP,FROM_SLIP);        /* BYU 2.4.16 - NCSA listen for SLIP */
  618.             if (fnum >= 0) {                        /* BYU 2.4.16 - signal that events should be caught */
  619.                 Sptypes[fnum] = PFTP;                /* BYU 2.4.16 */
  620.                 dataport[fnum] = -1;                /* BYU 2.4.16 - no data needed yet */
  621.                 mainstate[fnum] = 0;                /* BYU 2.4.16 */
  622.                 datastate[fnum] = 0;                /* BYU 2.4.16*/
  623.                 retnstate[fnum] = 200;                /* BYU 2.4.16 */
  624.             }                                        /* BYU 2.4.16 */
  625.         }                                            /* BYU 2.4.16 */
  626.     }                                                /* BYU 2.4.16 */
  627.  
  628.     strcpy((char *) myuser,"unknown");                /* BYU LSC - set unknown user name */
  629. }
  630.  
  631. void unsetftp
  632.   (
  633.     void
  634.   )
  635.     {
  636.     short i1;                            /* BYU 2.4.16 */
  637.  
  638.     rfstate = 0;
  639.     ftpstate = 0;
  640.     for (i1 = 0; i1 < NPORTS; i1++) {    /* BYU 2.4.16 */
  641.         if (Sptypes[i1] == PFTP) {        /* BYU 2.4.16 */
  642.             netclose(i1);                /* BYU 2.4.16 */
  643.             Sptypes[i1] = -1;            /* BYU 2.4.16 */
  644.             mainstate[i1] = 0;            /* BYU 2.4.16 */
  645.             datastate[i1] = 0;            /* BYU 2.4.16*/
  646.         }                                /* BYU 2.4.16 */
  647.     }                                    /* BYU 2.4.16 */
  648. /*    fnum = -1;                            /* BYU 2.4.16 */
  649.     ftpenable = 0;
  650. }
  651.  
  652. #if 0        /* BYU - Converted to STR# resource number 23227 */
  653. /***********************************************************************/
  654. /*
  655. *  resident ftp server -- enables initiation of ftp without a username
  656. *  and password, as long as this telnet is active at the same time
  657. *  Now checks for the need of passwords.
  658. */
  659.  
  660. static char *messs[] = {
  661. #ifdef PC
  662.                         "220 PC Resident FTP server, ready \015\012",
  663. #else
  664.                         "220 Macintosh Resident FTP server, ready \015\012",
  665. #endif
  666.                         "451 Error in processing list command \015\012",
  667.                         "221 Goodbye \015\012",                        /*2*/
  668.                         "200 This space intentionally left blank <   > \015\012",
  669.                         "150 Opening connection \015\012",
  670.                         "226 Transfer complete \015\012",            /*5*/
  671.                         "200 Type set to A, ASCII transfer mode \015\012",
  672.                         "200 Type set to I, binary transfer mode \015\012",
  673.                         "500 Command not understood \015\012",        /*8*/
  674.                         "200 Okay \015\012",
  675.                         "230 User logged in \015\012",
  676.                         "550 File not found \015\012",                /*11*/
  677.                         "501 Directory not present or syntax error\015\012",
  678.                         "250 Chdir okay\015\012",
  679.                         "257 \"",
  680.                         "\" is the current directory \015\012",        /*15*/
  681.                         "501 File not found \015\012",
  682.                         "504 Parameter not accepted, not implemented\015\012",
  683.                         "200 Stru F, file structure\015\012",
  684.                         "200 Mode S, stream mode\015\012",        /*19*/
  685.                         "202 Allocate and Account not required for this server\015\012",
  686.                         "501 Cannot open file to write, check for valid name\015\012",
  687.                         "530 USER and PASS required to activate me\015\012",
  688.                         "331 Password required\015\012",      /*23 */
  689.                         "530 Login failed\015\012",
  690.                         "200 MacBinary Mode enabled\015\012",
  691.                         "200 MacBinary Mode disabled\015\012",  /*26 */
  692.                         "552 Disk write error, probably disk full\015\012",
  693.                         "214-NCSA Telnet FTP server, supported commands:\015\012",
  694.                         "    USER  PORT  RETR  ALLO  PASS  STOR  CWD  XCWD  XPWD  LIST  NLST\015\012",
  695. #ifdef MAC
  696.                         "    HELP  QUIT  MODE  TYPE  STRU  ACCT  NOOP  MACB\015\012",  /*30*/
  697.                         "    MACB is MacBinary and must be done with TYPE I\015\012",
  698. #else
  699.                         "    HELP  QUIT  MODE  TYPE  STRU  ACCT  NOOP\015\012",
  700.                         "    A Macintosh version of NCSA Telnet is also available.\015\012",
  701. #endif
  702.                         "214 Direct comments and bugs to telbug@ncsa.uiuc.edu\015\012",
  703.                         "200 Type set to I, binary transfer mode [MACBINARY ENABLED]\015\012",                /* 33 */
  704.                         "200 Type set to I, binary transfer mode [macbinary disabled]\015\012",
  705.                 ""};
  706.  
  707. /***********************************************************************/
  708. #endif        /* BYU */
  709.  
  710. /* ftpgo
  711. *  open the FTP data connection to the remote host
  712. */
  713. int ftpgo
  714.   (
  715.     int fnum                /* BYU 2.4.16 */
  716.   )
  717.     {
  718.     int ftpdata,savest;        /* BYU 2.4.16 */
  719.     struct machinfo *m;
  720.  
  721.     xs[0] = portnum[fnum][0];
  722.     xs[1] = portnum[fnum][1];
  723.     xs[2] = portnum[fnum][2];
  724.     xs[3] = portnum[fnum][3];
  725.  
  726.     netfromport(20);     /* ftp data port */
  727.  
  728.     if (NULL == (m = Slookip(xs))) {        /* use default entry */
  729.         if (NULL == (m = Shostlook("default")))
  730.             return;
  731.         savest = m->mstat;
  732.         m->mstat = HAVEIP;
  733.         movebytes(m->hostip,xs,4);
  734. #if 0                                                                /* BYU 2.4.16 */
  735.         ftpdata = Snetopen(m,fdport,netporttype(fnum));                /* BYU 2.4.16 */
  736. #else                                                                /* BYU 2.4.16 */
  737.         ftpdata = Snetopen(m,fileport[fnum],netporttype(fnum));        /* BYU 2.4.16 */
  738. #endif                                                                /* BYU 2.4.16 */
  739.         m->mstat = savest;
  740.         memmove(m->hostip,(unsigned char *) "\0\0\0\0",(size_t) 4);    /* BYU LSC - was movebytes */
  741.         mainport[ftpdata] = fnum;                                    /* BYU 2.4.16 */
  742.         dataport[fnum] = ftpdata;                                    /* BYU 2.4.16 */
  743.         return(ftpdata);                                            /* BYU 2.4.16 */
  744.     }
  745.  
  746. #if 0                                                                /* BYU 2.4.16 */
  747.     ftpdata = Snetopen(m,fdport,netporttype(fnum));                    /* BYU 2.4.16 */
  748. #else                                                                /* BYU 2.4.16 */
  749.     ftpdata = Snetopen(m,fileport[fnum],netporttype(fnum));            /* BYU 2.4.16 */
  750. #endif                                                                /* BYU 2.4.16 */
  751.     mainport[ftpdata] = fnum;                                        /* BYU 2.4.16 */
  752.     dataport[fnum] = ftpdata;                                        /* BYU 2.4.16 */
  753.     return(ftpdata);                                                /* BYU 2.4.16 */
  754. }
  755.  
  756. void rftpd
  757.   (
  758.     int code,                                /* BYU 2.4.16 */
  759.     int fnum                                /* BYU 2.4.16 */
  760.   )
  761.     {
  762.     int fdport,ftpdata,i;                    /* BYU 2.4.16 */
  763.     char tempp[256];
  764.     char theDir[256];
  765.     if (!ftpenable)
  766.         return;
  767.  
  768.     netpush(fnum);
  769.  
  770.     rfstate = mainstate[fnum];                /* BYU 2.4.16 */
  771.     ftpstate = datastate[fnum];                /* BYU 2.4.16 */
  772.     retstate = retnstate[fnum];                /* BYU 2.4.16 */
  773.     fdport = fileport[fnum];                /* BYU 2.4.16 */
  774.  
  775.     switch (rfstate) {
  776.         case 0:
  777.             if (code != CONOPEN) 
  778.                 break;
  779.             ftpfilemode = FASCII;
  780.             ftptmode = FAMODE;
  781.             netputevent(USERCLASS,FTPCOPEN,-1);
  782. #ifndef PC
  783.             if (!xs) xs=(unsigned char *)NewPtr(BUFFERS+10);    /* BYU LSC */
  784.             if (!pathname) pathname=(unsigned char *)NewPtr(PATHLEN);
  785.             if (!newfile) newfile=(unsigned char *)NewPtr(PATHLEN);
  786. #endif PC
  787.             rfstate = 1;                /* drop through */
  788.         case 1:
  789.             CRESP(fnum,0);                            /* BYU 2.4.16 */
  790.             netgetftp(&portnum[fnum][0],fnum);        /* BYU 2.4.16 - get default ftp information */
  791.             for (i=0; i<4; i++)            /* copy IP number */
  792.                 hisuser[i] = portnum[fnum][i];                    /* BYU 2.4.16 */
  793.             fdport = portnum[fnum][6]*256+portnum[fnum][7];        /* BYU 2.4.16 */
  794.  
  795.             waitpos = 0; waitchar = '\012';
  796.             rfstate = 50;               /* note skips over */
  797.             if (Sneedpass()) 
  798.                 retstate = 3;                /* check pass */
  799.             else
  800.                 retstate = 5;                /* who needs one ? */
  801.             break;
  802.         case 3:                /* check for passwords */
  803.         case 4:
  804.             waitpos = 0;  waitchar = '\012';
  805.             rfstate = 50;  
  806.             if (!strncmp("USER",(char *) xs,4)) {    /* BYU LSC */
  807.                 if (strlen((char *) xs) < 6)        /* BYU LSC - make sure blank name stays blank */
  808.                     xs[5] = myuser[0] = 0;
  809.                 strncpy((char *) myuser,(char *) &xs[5],16);        /* BYU LSC - keep user name */
  810.                 netputevent(USERCLASS,FTPUSER,-1);
  811.                 CRESP(fnum,23);                                        /* BYU 2.4.16 */
  812.                 retstate = 4;        /* wait for password */
  813.                 break;
  814.             }
  815.             if (!strncmp("PASS",(char *) xs,4)) {                    /* BYU LSC */
  816.                 if (Scheckpass((char *) myuser,(char *) &xs[5])) {    /* BYU LSC */
  817.                     netputevent(USERCLASS,FTPPWOK,-1);
  818.                     CRESP(fnum,10);                                    /* BYU 2.4.16 */
  819.                     retstate = 5;
  820.                 }
  821.                 else {
  822.                     netputevent(USERCLASS,FTPPWNO,-1);
  823.                     CRESP(fnum,24);                                    /* BYU 2.4.16 */
  824.                     retstate = 3;
  825.                 }
  826.                 break;
  827.             }
  828.             if (!strncmp("QUIT",(char *) xs,4)) {    /* BYU LSC */
  829.                 CRESP(fnum,2);                        /* BYU 2.4.16 */
  830.                 cnt = -1;
  831.             }
  832.             else {
  833.                 CRESP(fnum,22);        /* BYU 2.4.16 */
  834.             }
  835.             retstate = 3;            /* must have password first */
  836.             break;                
  837.                 
  838. /*
  839. *  interpret commands that are received from the other side
  840. */
  841.             
  842.         case 5:
  843. #ifdef PC
  844.             for (i=4; i< strlen(xs); i++)
  845.                 if (xs[i] == '/')        /* flip slashes */
  846.                     xs[i] = '\\';
  847. #endif
  848.  
  849. /*
  850. *  set to a safe state to handle recursion
  851. *  wait for another command line from client
  852. *  
  853. */
  854.             rfstate = 50; retstate = 5;
  855.             waitchar = '\012';  waitpos = 0;
  856.  
  857.             if (!strncmp((char *) xs,"LIST",4) || !strncmp((char *) xs,"NLST",4)) {    /* BYU LSC */
  858.                 if ((strlen((char *) xs) < 6) || xs[5] == '.')        /* BYU LSC */
  859.                     strcpy((char *) xs,"LIST *");                    /* BYU LSC */
  860.  
  861.                 nextfile = firstname(&xs[5]);    /* find first name */
  862.                 if (nextfile == NULL) {
  863.                     CRESP(fnum,16);                /* BYU 2.4.16 */
  864.                 }
  865.                 else {
  866.                     ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open the connection */
  867.                     fdport = portnum[fnum][6]*256+portnum[fnum][7]; /* BYU 2.4.16 - reset to def */
  868.  
  869.                     if (ftpdata >= 0)
  870.                         Sptypes[ftpdata] = PDATA;
  871.                     ftpstate = 40;        /* ready to transmit */
  872.                     CRESP(fnum,4);                            /* BYU 2.4.16 */
  873.                     netputevent(USERCLASS,FTPLIST,-1);
  874.                 }
  875.             }
  876.             else if (!strncmp((char *) xs,"CWD",3)) {    /* BYU LSC */
  877.                 if (chgdir((char *) &xs[4])) {            /* BYU LSC - failed */
  878.                     CRESP(fnum,12);                        /* BYU 2.4.16 */
  879.                 }
  880.                 else {                        /* success */
  881.                     CRESP(fnum,13);            /* BYU 2.4.16 */
  882.                 }
  883.             }
  884.             else if (!strncmp((char *) xs,"STOR",4))    /* BYU LSC */
  885.               {
  886. #ifdef MACBINARY
  887.               /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  888.                 int
  889.                     MBflag;
  890.                 if ((!MacBinary) || (ftptmode == FAMODE))
  891.                     MBflag = MB_DISABLE;
  892.                 else
  893.                     MBflag = 0;
  894.                 mbfp = MBopen
  895.                   (
  896.                     &xs[5],
  897.                     defaultv,
  898.                     MB_WRITE | MBflag
  899.                   );
  900.                 if (mbfp == 0L)
  901.                   {
  902.                     CRESP(fnum,21);            /* BYU 2.4.16 */
  903.                     break;
  904.                   }
  905.                 else
  906.                     ftpfh = 12;
  907. #else
  908.  
  909.                 if (0 > (ftpfh = creat(&xs[5],ftpfilemode))) {
  910.                     CRESP(fnum,21);            /* BYU 2.4.16 */
  911.                     break;
  912.                 }
  913. #endif
  914.  
  915.                 ftpstate = 0;
  916.  
  917.                 strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1);    /* BYU LSC */
  918.                 
  919.  
  920.                 ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open connection */
  921.                 fdport = portnum[fnum][6]*256+portnum[fnum][7]; /* BYU 2.4.16 - reset to def */
  922.  
  923.                 if (ftpdata >= 0)
  924.                     Sptypes[ftpdata] = PDATA;
  925.  
  926.                 CRESP(fnum,4);        /* BYU 2.4.16 */
  927.  
  928.                 ftpstate = 30;        /* ready for data */
  929.               }
  930.  
  931.             else if (!strncmp((char *) xs,"RETR",4))    /* BYU LSC */
  932.               {
  933. #ifdef MACBINARY
  934.               /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  935.                 int
  936.                     MBflag;
  937.                 if ((!MacBinary) || (ftptmode == FAMODE))
  938.                     MBflag = MB_DISABLE;
  939.                 else
  940.                     MBflag = 0;
  941.                 mbfp = MBopen
  942.                   (
  943.                     &xs[5],
  944.                     defaultv,
  945.                     MB_READ | MBflag
  946.                   );
  947.                 if (mbfp == 0L) {
  948.                     CRESP(fnum,11);                        /* BYU 2.4.16 */
  949.                     break;
  950.                 }
  951.                 ftpfh = 12;
  952. #else
  953.                 if (0 > (ftpfh = open(&xs[5],ftpfilemode))) {
  954.                     CRESP(fnum,11);                        /* BYU 2.4.16 */
  955.                     break;
  956.                 }
  957. #endif
  958.                 strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1);    /* BYU LSC */
  959.  
  960.                 dopwd(theDir,256);                    /* get directory */
  961.                 sprintf(tempp,"remote <-- %s/%s\015\012",theDir,newfile);
  962.                 ftpmess(tempp);
  963.  
  964.                 ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open connection */
  965.                 fdport = portnum[fnum][6]*256+portnum[fnum][7]; /* BYU 2.4.16 - reset to def */
  966.  
  967.                 ftpstate = 20;        /* ready for data */
  968.                 if (ftpdata >= 0)
  969.                     Sptypes[ftpdata] = PDATA;
  970.  
  971.                 CRESP(fnum,4);                            /* BYU 2.4.16 */
  972.               }
  973.             else if (!strncmp((char *) xs,"TYPE",4)) {    /* BYU LSC */
  974.                 if (toupper(xs[5]) == 'I') {
  975.                     ftpfilemode = FIMAGE;
  976.                     ftptmode = FIMODE;
  977. #ifdef MACBINARY
  978.                 if (MacBinary) {
  979.                     CRESP(fnum,33);                    /* BYU 2.4.16 - Binary on, MACB ON */
  980.                 }
  981.                 else {
  982.                     CRESP(fnum,34);                    /* BYU 2.4.16 - Binary on, MACB off */
  983. #else
  984.                     CRESP(fnum,7);                    /* BYU 2.4.16 */
  985. #endif MACBINARY
  986.                 }
  987.                 }
  988.                 else if (toupper(xs[5]) == 'A') {
  989.                     ftpfilemode = FASCII;
  990.                     ftptmode = FAMODE;
  991.                     CRESP(fnum,6);                    /* BYU 2.4.16 */
  992.                 }
  993.                 else {
  994.                     CRESP(fnum,17);                    /* BYU 2.4.16 */
  995.                 }
  996.  
  997.             }
  998. #ifdef MACBINARY
  999.             else if (!strncmp((char *) xs,"MACB",4)) {    /* BYU LSC */
  1000.                 if (toupper(xs[5]) == 'E') {
  1001.                     MacBinary = 1;
  1002.                     CRESP(fnum,25);                    /* BYU 2.4.16 */
  1003.                 }
  1004.                 else {
  1005.                     MacBinary = 0;
  1006.                     CRESP(fnum,26);                    /* BYU 2.4.16 */
  1007.                 }
  1008.                 DisplayMacBinary();            /* post an event ? */
  1009.             }
  1010. #endif
  1011.             else if (!strncmp((char *) xs,"PORT",4)) {    /* BYU LSC */
  1012. /*
  1013. * get the requested port number from the command given
  1014. */
  1015.                 sscanf((char *) &xs[5],"%d,%d,%d,%d,%d,%d",        /* BYU 2.4.16 */
  1016.                     &portnum[fnum][0],&portnum[fnum][1],        /* BYU 2.4.16 */
  1017.                     &portnum[fnum][2],&portnum[fnum][3],        /* BYU 2.4.16 */
  1018.                     &portnum[fnum][4],&portnum[fnum][5]);        /* BYU 2.4.16 */
  1019.                 fdport = portnum[fnum][4]*256+portnum[fnum][5];    /* BYU 2.4.16 */
  1020.                 CRESP(fnum,3);                            /* BYU 2.4.16 */
  1021.             }
  1022.             else if (!strncmp((char *) xs,"QUIT",4)) {    /* BYU LSC */
  1023.                 CRESP(fnum,2);                            /* BYU 2.4.16 */
  1024.                 rfstate = 60;
  1025.                 netputuev(CONCLASS,CONDATA,fnum);    /* post back to me */
  1026.             }
  1027.             else if (!strncmp((char *) xs,"XPWD",4) || !strncmp((char *) xs,"PWD",3)) {    /* BYU LSC */
  1028.                 CRESP(fnum,14);                        /* BYU 2.4.16 - start reply */
  1029.                 dopwd((char *) xs,1000);        /* BYU LSC - get directory */
  1030.                 netwrite(fnum,(char *) xs,strlen((char *) xs));    /* BYU LSC - write dir name */
  1031.                 CRESP(fnum,15);                        /* BYU 2.4.16 - finish reply */
  1032.             }
  1033.             else if (!strncmp((char *) xs,"USER",4)) {    /* BYU LSC */
  1034.                 if (strlen((char *) xs) < 6)            /* BYU LSC - make sure blank name stays blank */
  1035.                     xs[5] = myuser[0] = 0;
  1036.                 strncpy((char *) myuser,(char *) &xs[5],16);    /* BYU LSC - keep user name */
  1037.                 netputevent(USERCLASS,FTPUSER,-1);
  1038.                 /* confirm log in without password */
  1039.                 CRESP(fnum,10);                            /* BYU 2.4.16 */
  1040.             }
  1041.             else if (!strncmp((char *) xs,"STRU",4)) {    /* BYU LSC - only one stru allowed */
  1042.                 if (xs[5] == 'F') {
  1043.                     CRESP(fnum,18); }                    /* BYU 2.4.16 */
  1044.                 else {
  1045.                     CRESP(fnum,17); }                    /* BYU 2.4.16 */
  1046.             }
  1047.             else if (!strncmp((char *) xs,"MODE",4)) {    /* BYU LSC - only one mode allowed */
  1048.                 if (xs[5] == 'S') {
  1049.                     CRESP(fnum,19); }                    /* BYU 2.4.16 */
  1050.                 else {
  1051.                     CRESP(fnum,17); }                    /* BYU 2.4.16 */
  1052.             }
  1053.             else if (!strncmp((char *) xs,"ALLO",4) || !strncmp((char *) xs,"ACCT",4)) {    /* BYU LSC */
  1054.                 CRESP(fnum,20); }                        /* BYU 2.4.16 */
  1055.             else if (!strncmp((char *) xs,"HELP",4)) {    /* BYU LSC */
  1056.                 for (i=28; i<33; i++) {
  1057.                     CRESP(fnum,i); }                    /* BYU 2.4.16 */
  1058.             }
  1059.             else if (!strncmp((char *) xs,"NOOP",4)) {        /* BYU LSC */
  1060.                 CRESP(fnum,9); }                            /* BYU 2.4.16 */
  1061.             else {            /* command not understood */
  1062.                 CRESP(fnum,8);                                 /* BYU 2.4.16 */
  1063.             }
  1064.  
  1065.             break;
  1066.  
  1067. /*
  1068. *  subroutine to wait for a particular character
  1069. */
  1070.         case 50:
  1071.             while (0 < (cnt = netread(fnum,&xs[waitpos],1))) {
  1072.                 if (xs[waitpos] == waitchar) {
  1073.                     rfstate = retstate;
  1074.  
  1075.                     while (xs[waitpos] < 33)        /* find end of string */
  1076.                         waitpos--;
  1077.                     xs[++waitpos] = '\0';            /* put in terminator */
  1078.  
  1079.                     for (i=0; i<4; i++)                /* want upper case */
  1080.                         xs[i] = toupper(xs[i]);
  1081.  
  1082.                     break;
  1083.                 }
  1084.                 else
  1085.                     waitpos += cnt;
  1086.  
  1087.             }
  1088.             break;
  1089.  
  1090.         case 60:                    /* wait for message to get through */
  1091.                                     /* or connection is broken */
  1092. /*            printf("                  %d,%d",netpush(fnum),netest(fnum));*/
  1093.             if (!netpush(fnum) || netest(fnum))
  1094.                 cnt = -1;
  1095.             else
  1096.                 netputuev(CONCLASS,CONDATA,fnum);    /* post back to me */
  1097.             break;
  1098.  
  1099.         default:
  1100.             break;
  1101.  
  1102.     }
  1103.  
  1104.     if (cnt < 0) {
  1105. #ifdef MACBINARY
  1106.         if (mbfp) {
  1107.             MBclose( mbfp );
  1108.             mbfp = NULL;
  1109.         }
  1110. #else
  1111.         if (ftpfh > 0) {
  1112.             ftpfh = 0;
  1113.             close(ftpfh);
  1114.         }
  1115. #endif
  1116.         ftpdata = dataport[fnum];                    /* BYU 2.4.16 */
  1117.         if (ftpdata > 0) {
  1118.             netclose(ftpdata);
  1119.             netputevent(USERCLASS,FTPEND,-1);
  1120.             dataport[fnum] = -1;                    /* BYU 2.4.16 */
  1121.             mainport[ftpdata] = -1;                    /* BYU 2.4.16 */
  1122.         }
  1123.         rfstate = 100;
  1124.         ftpstate = 0;
  1125.         cnt = 0;
  1126.         netclose(fnum);
  1127.         Sptypes[fnum] = -1;                            /* BYU 2.4.16 */
  1128.         netputevent(USERCLASS,FTPCLOSE,-1);
  1129. #if 0                                                /* BYU 2.4.16 */
  1130.         fnum = -1;
  1131.         ftpdata = -1;
  1132. #endif                                                /* BYU 2.4.16 */
  1133.         setftp();                /* reset it */
  1134.     }
  1135.  
  1136.     mainstate[fnum] = rfstate;                        /* BYU 2.4.16 */
  1137.     datastate[fnum] = ftpstate;                        /* BYU 2.4.16 */
  1138.     retnstate[fnum] = retstate;                        /* BYU 2.4.16 */
  1139.     fileport[fnum] = fdport;                        /* BYU 2.4.16 */
  1140.  
  1141. }
  1142.  
  1143. /*
  1144. *  important note:  for Sfread, nwant must be 256 bytes LARGER than the amount
  1145. *  which will probably be read from the connection.
  1146. *  Sfread will stop anywhere from 0 to 256 bytes short of filling nwant
  1147. *  number of bytes.
  1148. */
  1149. int Sfread
  1150.   (
  1151.     int pnum,
  1152.     char *buf,        /* BYU LSC */
  1153.     int nwant
  1154.   )
  1155.     {
  1156.     int i,ndone,lim;
  1157.     char *p,*q;
  1158.  
  1159.     if (nwant < 1024)
  1160.         return(-1);
  1161.  
  1162.     ndone = 0;
  1163.  
  1164.     while (ndone < nwant - 1024) {
  1165.  
  1166.         if (0 >= (lim = netread(pnum,mungbuf,1024))) {
  1167.             if (ndone || !lim)            /* if this read is valid, but no data */
  1168.                 return(ndone);
  1169.             else
  1170.                 return(-1);                /* if connection is closed for good */
  1171.         }
  1172.  
  1173.         p = mungbuf;
  1174.         q = (char *) buf + ndone;
  1175.  
  1176. /*        printf("\012 lim=%d done=%d want=%d",lim,ndone,nwant);
  1177.         n_row();
  1178. */
  1179.         for (i=0; i < lim; i++) {
  1180.  
  1181.             if (crfound) {
  1182.                 if (*p == 10)
  1183.                     *q++ = EOLCHAR;
  1184.                 else if (*p == 0)
  1185.                     *q++ = 13;            /* CR-NUL means CR */
  1186.                 crfound = 0;
  1187.             }
  1188.             else if (*p == 13)
  1189.                 crfound = 1;
  1190.             else 
  1191.                 *q++ = *p;                /* copy the char */
  1192.  
  1193.             p++;
  1194.         }
  1195.  
  1196.         ndone = q-buf;                    /* count chars ready */
  1197.     }
  1198.  
  1199.     return(ndone);
  1200. }
  1201.  
  1202. /***************************************************************************/
  1203. /*  Sfwrite
  1204. *   Write an EOL translated buffer into netwrite.
  1205. *   Returns the number of bytes which were processed from the incoming
  1206. *   buffer.  Uses its own 1024 byte buffer for the translation (with Sfread).
  1207. */
  1208.  
  1209. int Sfwrite
  1210.   (
  1211.     int pnum,
  1212.     void *buf,
  1213.     int nsrc
  1214.   )
  1215.     {
  1216.     int i,ndone,nout,lim;
  1217.     char *p,*q;
  1218.  
  1219.     ndone = 0;
  1220.  
  1221.     while (ndone < nsrc) {
  1222.  
  1223.         if (0 > ( i = netroom(pnum)))
  1224.             return(-1);
  1225.  
  1226.         if (i < 1024)                    /* not enough room to work with */
  1227.             return(ndone);
  1228. /*
  1229. *  process up to 512 source bytes for output (could produce 1K bytes out) 
  1230. */
  1231.         if (nsrc - ndone > 512)
  1232.             lim = 512;
  1233.         else
  1234.             lim = nsrc-ndone;
  1235.  
  1236.         p = (char *) buf + ndone;                /* where to start this block */
  1237.         q = mungbuf;                    /* where munged stuff goes */
  1238.         for (i=0; i < lim; i++) {
  1239.             if (*p == EOLCHAR) {
  1240.                 *q++ = 13;
  1241.                 *q++ = 10;
  1242.                 p++;
  1243.             }
  1244.             else
  1245.                 *q++ = *p++;
  1246.         }
  1247.         ndone += lim;                    /* # of chars processed */
  1248.         nout = q-mungbuf;                /* # of chars new */
  1249.  
  1250.         if ( nout != netwrite(pnum,mungbuf,nout) )
  1251.             putln("error in Sfwrite");    /* send them on their way */
  1252.  
  1253.     }
  1254.  
  1255.     return(ndone);
  1256. }
  1257.  
  1258. /*********************************************************************/
  1259. /*
  1260. *  FTP receive and send file functions
  1261. */
  1262. static int fcnt=0;
  1263.  
  1264. void ftpd
  1265.   (
  1266.     int code,
  1267.     int ftpdata                            /* BYU 2.4.16 */
  1268.   )
  1269.     {
  1270.     short fnum = mainport[ftpdata];        /* BYU 2.4.16 */
  1271.     int i,a;
  1272.     char tempp[256];
  1273.     char theDir[256];
  1274.  
  1275. /*    if (curcon != ftpdata)                /* BYU 2.4.16 - wrong event, was for someone else */
  1276. /*        return;                            /* BYU 2.4.16 */
  1277.  
  1278.     ftpstate = datastate[fnum];            /* BYU 2.4.16 */
  1279.  
  1280.     switch (ftpstate) {
  1281.         default:
  1282.             break;
  1283.  
  1284.         case 40:                /* list file names in current dir */
  1285.  
  1286.             if (code == CONFAIL)    /* something went wrong */
  1287.                 fcnt = -1;
  1288.             if (code != CONOPEN)     /* waiting for connection to open */
  1289.                 break;
  1290.             
  1291.             ftpstate = 41;
  1292.  
  1293. /*
  1294. *  send the "nextfile" string and then see if there is another file
  1295. *  name to send
  1296. */
  1297.         case 41:
  1298.             netputuev(SCLASS,FTPACT,ftpdata);
  1299.             netpush(ftpdata);
  1300.             strcpy(tempp,nextfile);                    /* BYU 2.4.13 */
  1301.             strcat(tempp,"\015\012");                /* BYU 2.4.13 */
  1302.             i = strlen(tempp);                        /* BYU 2.4.13 */
  1303.             if (i != netwrite(ftpdata,tempp,i)) {    /* BYU 2.4.13 */
  1304.                 CRESP(fnum,1);                        /* BYU 2.4.16 */
  1305.                 fcnt = -1;
  1306.                 break;
  1307.             }
  1308. /*            netwrite(ftpdata,"\015\012",2);            /* BYU 2.4.13 */
  1309.  
  1310.             if (NULL == (nextfile = nextname())) {    /* normal end */
  1311.                 ftpstate = 22;               /* push data through */
  1312.             }
  1313.             break;
  1314.             
  1315.         case 30:
  1316.             if (code == CONFAIL)    /* something went wrong */
  1317.                 fcnt = -1;
  1318.             if (code != CONOPEN)    /* waiting for connection to open */
  1319.                 break;
  1320.             ftpstate = 31;
  1321.             crfound = 0;
  1322.             len = xp = 0;
  1323.             filelen = 0L;
  1324.             dopwd(theDir,256);                    /* get directory */
  1325.             sprintf(tempp,"remote --> %s/%s\015\012",theDir,newfile);
  1326.             ftpmess(tempp);
  1327.             netputevent(USERCLASS,FTPBEGIN,-2);
  1328.             
  1329.         case 31:
  1330. /*
  1331. * file has already been opened, take everything from the connection
  1332. * and place into the open file: ftpfh
  1333. */
  1334.             do {
  1335.             /* wait until xs is full before writing to disk */
  1336.                 if (len <= 2000) {
  1337.  
  1338.                     if (xp) {
  1339. #ifdef MACBINARY
  1340.                         if (0 > MBwrite(mbfp, xs, xp)) {
  1341.                             MBclose( mbfp);            /* Close on Disk Full Error */
  1342.                             ftpstate=22;
  1343.                             CRESP(fnum,27);                /* BYU 2.4.16 */
  1344.                             ftpmess((char *) messs);    /* BYU LSC */
  1345.                             if( (a = netclose(ftpdata)) !=0 ) putln("error closing net ");
  1346.                             fcnt = -1;
  1347.                             mbfp=NULL;
  1348.  
  1349.                             putln("there is a problem");
  1350.                             break;
  1351.                         }
  1352. #else
  1353.                         if (0 > write(ftpfh,xs,xp)) { /* disk full err */
  1354.                             putln("\015\012we have a disk full error in asc\015\012");
  1355.  
  1356.                             CRESP(fnum,27);                /* BYU 2.4.16 */
  1357.                             netclose(ftpdata);
  1358.                             fcnt = -1;
  1359.  
  1360.                             break;
  1361.                         }
  1362. #endif
  1363.                         xp = 0;
  1364.                     }
  1365.                     len = BUFFERS;        /* expected or desired len to go */
  1366.                 }
  1367.  
  1368.                 if (ftptmode == FAMODE)
  1369.                     fcnt = Sfread(ftpdata,(char *) &xs[xp],len);    /* BYU LSC */
  1370.                 else
  1371.                     fcnt = netread(ftpdata,&xs[xp],len);
  1372.  
  1373.                 if (fcnt >= 0) {
  1374.                     len -= fcnt;
  1375.                     xp += fcnt;
  1376.                     filelen += fcnt;
  1377.                 }
  1378.  
  1379.                 if (fcnt < 0) {
  1380. #ifdef MACBINARY
  1381.                     if (0 > MBwrite( mbfp, xs, xp)) {
  1382.                         CRESP(fnum,27);            /* BYU 2.4.16 */
  1383.                         MBclose( mbfp);            /* Close file on error */
  1384.                         break;
  1385.                     }
  1386.                     MBclose( mbfp );
  1387. #else
  1388.                     if (0 > write(ftpfh,xs,xp)) { /* disk full check */
  1389.                         CRESP(fnum,27);                /* BYU 2.4.16 */
  1390.                         break;
  1391.                     }
  1392.                     close(ftpfh);
  1393. #endif
  1394.                     ftpfh = 0;
  1395.                     CRESP(fnum,5);                    /* BYU 2.4.16 */
  1396.                 }
  1397.  
  1398.             } while (fcnt > 0);
  1399.             break;
  1400.  
  1401.         case 20:
  1402.  
  1403.             if (code == CONFAIL)    /* something went wrong */
  1404.                 fcnt = -1;
  1405.             if (code != CONOPEN)    /* waiting for connection to open */
  1406.                 break;
  1407.             ftpstate = 21;
  1408. #ifdef MACBINARY
  1409.             filelen = MBsize( mbfp );
  1410. #else
  1411.             filelen = lseek(ftpfh,0L,2);        /* how long is file? */
  1412.             lseek(ftpfh,0L,0);                    /* back to beginning */
  1413. #endif
  1414.             towrite = 0;
  1415.             xp = 0;
  1416.             netputevent(USERCLASS,FTPBEGIN,-1);
  1417.  
  1418.         case 21:
  1419. /*
  1420. *  transfer file(s) to the other host via ftp request
  1421. *  file is already open = ftpfh
  1422. */
  1423.             netputuev(SCLASS,FTPACT,ftpdata);
  1424.         
  1425.             if (towrite <= xp) {
  1426.  
  1427.                 i = BUFFERS;
  1428. #ifdef MACBINARY
  1429.                 towrite = MBread( mbfp, xs, i);
  1430. #else
  1431.                 towrite = read(ftpfh,xs,i);
  1432. #endif
  1433.                 xp = 0;
  1434.             }
  1435.  
  1436.             if (towrite <= 0 || netest(ftpdata)) {        /* we are done */
  1437.                 ftpstate = 22;
  1438.                 break;
  1439.             }
  1440.  
  1441.             if (ftptmode == FAMODE)
  1442.                 i = Sfwrite(ftpdata,&xs[xp],towrite-xp);
  1443.             else
  1444.                 i = netwrite(ftpdata,&xs[xp],towrite-xp);
  1445.  
  1446.  
  1447. /*            printf(" %d %d %d \012",i,xp,towrite);
  1448.             n_row(); */
  1449.  
  1450.             if (i > 0) {
  1451.                 xp += i;
  1452.                 filelen -= i;
  1453.                 if (filelen < 0L)
  1454.                     filelen = 0L;
  1455.             }
  1456.  
  1457.             break;
  1458.  
  1459.         case 22:        /* wait for data to be accepted */
  1460.             netputuev(SCLASS,FTPACT,ftpdata);
  1461.  
  1462.             fcnt = netpush(ftpdata);        /* will go negative on err */
  1463.             if (!fcnt || netest(ftpdata))
  1464.                 fcnt = -1;
  1465.             if (fcnt < 0) {
  1466.                 CRESP(fnum,5);                /* BYU 2.4.16 */
  1467.             }
  1468.             break;
  1469.  
  1470.         case 0:
  1471.             break;
  1472.  
  1473.     }  /* end of switch */
  1474.  
  1475. /*
  1476. *  after reading from connection, if the connection is closed,
  1477. *  reset up shop.
  1478. */
  1479.     if (fcnt < 0) {
  1480. #ifdef MACBINARY
  1481.         if (mbfp) {
  1482.             MBclose( mbfp );
  1483.             mbfp = NULL;
  1484.  
  1485.  
  1486.  
  1487. /* */        
  1488.         }
  1489. #else
  1490.         if (ftpfh > 0) {
  1491.             close(ftpfh);
  1492.             ftpfh = 0;
  1493.         }
  1494. #endif
  1495.         ftpstate = 0;
  1496.         fcnt = 0;
  1497.         if (ftpdata >= 0) {
  1498.             netclose(ftpdata);
  1499.             netputevent(USERCLASS,FTPEND,-1);
  1500. /*            ftpdata = -1;                        /* BYU 2.4.16 */
  1501.             mainport[ftpdata] = -1;                /* BYU 2.4.16 */
  1502.             dataport[fnum] = -1;                /* BYU 2.4.16 */
  1503.         }
  1504.     }
  1505.  
  1506.     datastate[fnum] = ftpstate;            /* BYU 2.4.16 */
  1507.  
  1508. }
  1509.  
  1510. /***********************************************************************/
  1511. /* Sftpname and Sftpuser and Sftphost
  1512. *  record the name of the file being transferred, to use in the status
  1513. *  line updates
  1514. */
  1515.  
  1516. void Sftpname
  1517.   (
  1518.     char *s
  1519.   )
  1520.   {
  1521.     strcpy(s, (char *) newfile);    /* BYU LSC */
  1522.   }
  1523.  
  1524. void Sftpuser
  1525.   (
  1526.     char *user
  1527.   )
  1528.   {
  1529.     strcpy(user, (char *) myuser);    /* BYU LSC - user name entered to log in */
  1530.   }
  1531.  
  1532. void Sftphost
  1533.   (
  1534.     char *host
  1535.   )
  1536.   {
  1537.     memmove((unsigned char *) host,(unsigned char *) hisuser,(size_t) 4);        /* BYU LSC - IP address of remote host */
  1538.   }
  1539.  
  1540. void Sftpstat
  1541.   (
  1542.     long *byt
  1543.   )
  1544.     {
  1545.     
  1546.     if (ftptmode != FAMODE && MacBinary)    /* MacBinary transfer */
  1547.         *byt = -1;
  1548.     else
  1549.         *byt = filelen;
  1550.  
  1551. }
  1552.  
  1553. #ifdef MACBINARY
  1554. void MBstat
  1555.   (
  1556.     char nlen,
  1557.     int godknows,
  1558.     int anotherlen
  1559.   )
  1560.   {
  1561. #pragma unused(nlen, godknows, anotherlen)
  1562.   }
  1563. #endif
  1564.